﻿using System;
using System.IO;
using System.Runtime.Serialization.Json;
using System.Text;
namespace RapidRepository
{
    /// <summary>
    /// Contains methods for serialisation and deserialisation of entities.
    /// </summary>
    internal class Serialiser : ISerialiser
    {
        #region Serialise

        /// <summary>
        /// Serialises the specified type.
        /// </summary>
        /// <param name="type">The type.</param>
        /// <param name="objectToSerialise">The object to serialise.</param>
        public string Serialise(Type type, object objectToSerialise)
        {
            Contract.Requires("type", type != null);
            Contract.Requires("objectToSerialise", objectToSerialise != null);

            DataContractJsonSerializer serialiser = new DataContractJsonSerializer(type);
            MemoryStream memoryStream = new MemoryStream();
            serialiser.WriteObject(memoryStream, objectToSerialise);
            string serialisedObject = Encoding.UTF8.GetString(memoryStream.ToArray(), 0, (int)memoryStream.Length);
            memoryStream.Dispose();
            return serialisedObject;
        }

        #endregion

        #region Deserialise

        /// <summary>
        /// Deserialises the specified string.
        /// </summary>
        /// <typeparam name="T">The type of the object.</typeparam>
        /// <param name="stringToDeserialise">The string to deseralise.</param>
        public T Deserialise<T>(string stringToDeserialise)
        {
            Contract.Requires("stringToDeseralise", !string.IsNullOrEmpty(stringToDeserialise));

            return (T)Deserialise(typeof(T), stringToDeserialise);
        }

        /// <summary>
        /// Deserialises the specified view type.
        /// </summary>
        /// <param name="viewType">Type of the view.</param>
        /// <param name="stringToDeserialise">The string to deserialise.</param>
        public object Deserialise(Type viewType, string stringToDeserialise)
        {
            Contract.Requires("viewType", viewType != null);
            Contract.Requires("stringToDeseralise", !string.IsNullOrEmpty(stringToDeserialise));

            object entity = Activator.CreateInstance(viewType);
            MemoryStream memoryStream = new MemoryStream(Encoding.Unicode.GetBytes(stringToDeserialise));
            DataContractJsonSerializer serialiser = new DataContractJsonSerializer(viewType);
            entity = serialiser.ReadObject(memoryStream);
            memoryStream.Close();
            memoryStream.Dispose();
            return entity;
        } 

        #endregion
    }
}
